{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2024-05-23T09:30:51.710374300Z",
     "start_time": "2024-05-23T09:30:50.380983800Z"
    }
   },
   "outputs": [],
   "source": [
    "from sklearn.datasets import fetch_california_housing\n",
    "from sklearn.linear_model import LinearRegression, SGDRegressor, Ridge, LogisticRegression, Lasso\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.metrics import mean_squared_error, classification_report, roc_auc_score\n",
    "import joblib\n",
    "import pandas as pd\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "source": [
    "# 回归预测房价"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "获取形状\n",
      "(20640, 8)\n",
      "<class 'numpy.ndarray'>\n",
      "(20640,)\n",
      "<class 'numpy.ndarray'>\n",
      "--------------------------------------------------\n",
      "第一个样本的特征值\n",
      "[   8.3252       41.            6.98412698    1.02380952  322.\n",
      "    2.55555556   37.88       -122.23      ]\n",
      "--------------------------------------------------\n",
      "前10个样本的目标值\n",
      "4.526\n",
      "[4.526 3.585 3.521 3.413 3.422 2.697 2.992 2.414 2.267 2.611]\n",
      "最高最低房价： 5.00001 0.14999\n",
      "--------------------------------------------------\n",
      "['MedInc', 'HouseAge', 'AveRooms', 'AveBedrms', 'Population', 'AveOccup', 'Latitude', 'Longitude']\n"
     ]
    }
   ],
   "source": [
    "# 获取数据\n",
    "lb = fetch_california_housing(data_home='data')\n",
    "\n",
    "print(\"获取形状\")\n",
    "print(lb.data.shape)\n",
    "print(type(lb.data))\n",
    "print(lb.target.shape)\n",
    "print(type(lb.target))\n",
    "print('-' * 50)\n",
    "\n",
    "print(\"第一个样本的特征值\")\n",
    "print(lb.data[0])\n",
    "print('-' * 50)\n",
    "\n",
    "print(\"前10个样本的目标值\")\n",
    "print(lb.target[0])\n",
    "print(lb.target[:10])\n",
    "print(\"最高最低房价：\", np.max(lb.target), np.min(lb.target))\n",
    "# print(lb.DESCR)\n",
    "print('-' * 50)\n",
    "\n",
    "# 特征名称\n",
    "print(lb.feature_names)\n"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-23T09:30:51.729080600Z",
     "start_time": "2024-05-23T09:30:51.714384Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "MedInc - 中位收入（Median Income）\n",
    "HouseAge - 房屋年龄（House Age）\n",
    "AveRooms - 平均房间数（Average Number of Rooms）\n",
    "AveBedrms - 平均卧室数（Average Number of Bedrooms）\n",
    "Population - 人口数量（Population）\n",
    "AveOccup - 平均居住人数（Average Occupancy）\n",
    "Latitude - 纬度（Latitude）\n",
    "Longitude - 经度（Longitude）"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "outputs": [],
   "source": [
    "# 分割数据集到训练集和测试集\n",
    "x_train, x_test, y_train, y_test = train_test_split(lb.data, lb.target, test_size=0.25, random_state=1)\n"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-23T09:30:51.795283500Z",
     "start_time": "2024-05-23T09:30:51.733240100Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "outputs": [],
   "source": [
    "# 进行标准化处理、目标值处理\n",
    "# 特征值和目标值是都必须进行标准化处理, 实例化两个标准化API\n",
    "std_x = StandardScaler()\n",
    "\n",
    "x_train = std_x.fit_transform(x_train)\n",
    "x_test = std_x.transform(x_test)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-23T09:30:51.809399600Z",
     "start_time": "2024-05-23T09:30:51.745921Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'numpy.ndarray'>\n",
      "<class 'numpy.ndarray'>\n",
      "<class 'numpy.ndarray'>\n",
      "<class 'numpy.ndarray'>\n"
     ]
    }
   ],
   "source": [
    "print(type(x_train))\n",
    "print(type(x_test))\n",
    "print(type(y_train))\n",
    "print(type(y_test))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-23T09:30:51.809399600Z",
     "start_time": "2024-05-23T09:30:51.759555600Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(15480, 8)\n",
      "(5160, 8)\n",
      "(15480,)\n",
      "(5160,)\n"
     ]
    }
   ],
   "source": [
    "print(x_train.shape)\n",
    "print(x_test.shape)\n",
    "print(y_train.shape)\n",
    "print(y_test.shape)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-23T09:30:51.809399600Z",
     "start_time": "2024-05-23T09:30:51.771555300Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "outputs": [],
   "source": [
    "# 目标值进行了标准化\n",
    "std_y = StandardScaler()\n",
    "\n",
    "# 标签也进行标准化，可以和标签不标准化进行对比，看一下哪个误差比较小\n",
    "y_train = std_y.fit_transform(y_train.reshape(-1, 1)) # 目标值是一维的，这里需要传进去2维的\n",
    "y_test = std_y.transform(y_test.reshape(-1, 1))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-23T09:30:51.809399600Z",
     "start_time": "2024-05-23T09:30:51.795283500Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'numpy.ndarray'>\n",
      "<class 'numpy.ndarray'>\n",
      "<class 'numpy.ndarray'>\n",
      "<class 'numpy.ndarray'>\n"
     ]
    }
   ],
   "source": [
    "print(type(x_train))\n",
    "print(type(x_test))\n",
    "print(type(y_train))\n",
    "print(type(y_test))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-23T09:30:51.809399600Z",
     "start_time": "2024-05-23T09:30:51.800297Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(15480, 8)\n",
      "(5160, 8)\n",
      "(15480, 1)\n",
      "(5160, 1)\n"
     ]
    }
   ],
   "source": [
    "print(x_train.shape)\n",
    "print(x_test.shape)\n",
    "print(y_train.shape)\n",
    "print(y_test.shape)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-23T09:30:51.892539300Z",
     "start_time": "2024-05-23T09:30:51.813406700Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1]\n",
      " [2]\n",
      " [3]]\n",
      "[1 2 3]\n"
     ]
    }
   ],
   "source": [
    "test1=np.array([1,2,3])\n",
    "print(test1.reshape(-1,1))\n",
    "print(test1)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-23T09:31:02.903705800Z",
     "start_time": "2024-05-23T09:31:02.848767700Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 1、 正规方程求解"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "回归系数：\n",
      " [[ 0.71942632  0.10518431 -0.23147194  0.26802332 -0.00448136 -0.03495117\n",
      "  -0.7849086  -0.76307353]]\n",
      "--------------------------------------------------\n",
      "测试集里前10个房子的预测价格：\n",
      " [[ 0.039975  ]\n",
      " [-0.9856667 ]\n",
      " [ 0.54595901]\n",
      " [-0.31917221]\n",
      " [ 0.65037085]\n",
      " [ 1.23359413]\n",
      " [ 0.81054876]\n",
      " [-0.38917515]\n",
      " [-0.28938242]\n",
      " [-0.05080248]]\n",
      "--------------------------------------------------\n",
      "正规方程的均方误差： 0.40082431136214197\n"
     ]
    }
   ],
   "source": [
    "# # estimator预测\n",
    "\n",
    "lr = LinearRegression()\n",
    "\n",
    "# fit是耗时的\n",
    "lr.fit(x_train, y_train)\n",
    "\n",
    "# 回归系数可以看特征与目标之间的相关性，即每个特征对目标值的影响程度\n",
    "print('回归系数：\\n', lr.coef_)\n",
    "print(\"-\"*50)\n",
    "\n",
    "# 预测\n",
    "y_predict = lr.predict(x_test)\n",
    "\n",
    "# 预测测试集的房子价格，通过inverse得到真正的房子价格\n",
    "#y_lr_predict = std_y.inverse_transform(y_predict)\n",
    "\n",
    "# 保存训练好的模型，模型中保存的是w的值，也保存了模型结构\n",
    "# 保存模型放在fit之后即可\n",
    "#joblib.dump(lr, \"./tmp/test.pkl\")\n",
    "\n",
    "print(\"测试集里前10个房子的预测价格：\\n\", y_predict[0:10])\n",
    "#print(\"测试集里前10个房子的预测价格：\\n\", y_lr_predict[0:10])\n",
    "print(\"-\"*50)\n",
    "\n",
    "# 求测试集的损失\n",
    "print(\"正规方程的均方误差：\", mean_squared_error(y_test, y_predict))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-23T09:31:05.380406700Z",
     "start_time": "2024-05-23T09:31:05.335401Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 加载保存的模型"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'sklearn.linear_model._base.LinearRegression'>\n",
      "--------------------------------------------------\n",
      "保存的模型预测的结果：\n",
      " [2.12391852 0.93825754 2.7088455  1.70873764 2.82954754 3.50376456\n",
      " 3.0147162  1.62781292 1.74317518 2.01897806]\n",
      "正规方程的均方误差：\n",
      " 4.798956131502183\n"
     ]
    }
   ],
   "source": [
    "model = joblib.load(\"./tmp/test.pkl\")\n",
    "# # 因为目标值进行了标准化，一定要把预测后的值逆向转换回来\n",
    "y_predict = model.predict(x_test)\n",
    "\n",
    "print(type(model))\n",
    "print(\"-\"*50)\n",
    "\n",
    "print(\"保存的模型预测的结果：\\n\", y_predict[:10])\n",
    "print(\"正规方程的均方误差：\\n\", mean_squared_error(y_test, y_predict))\n",
    "\n",
    "# print(\"正规方程inverse后的均方误差：\", mean_squared_error(std_y.inverse_transform(y_test),\n",
    "#                                                std_y.inverse_transform(y_predict)))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-22T14:26:44.573706400Z",
     "start_time": "2024-05-22T14:26:44.534942200Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.375\n",
      "0.375\n"
     ]
    }
   ],
   "source": [
    "y_true = [3, -0.5, 2, 7]\n",
    "y_pred = [2.5, 0.0, 2, 8]\n",
    "print(mean_squared_error(y_true, y_pred))\n",
    "\n",
    "# 人工求均方误差\n",
    "print((np.square(3 - 2.5) + np.square(0.5) + 1) / 4)\n"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-23T09:31:52.100368800Z",
     "start_time": "2024-05-23T09:31:52.078276500Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 2、 随机梯度下降"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "梯度下降的回归系数 [ 0.70786432  0.112551   -0.15889175  0.30422911 -0.0122361  -0.0032661\n",
      " -0.7980291  -0.76143771]\n",
      "梯度下降的均方误差： 0.40795678399475427\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\3.8\\lib\\site-packages\\sklearn\\utils\\validation.py:1183: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().\n",
      "  y = column_or_1d(y, warn=True)\n"
     ]
    }
   ],
   "source": [
    "# 梯度下降去进行房价预测,数据量大要用这个\n",
    "# learning_rate，学习率调整的方式，\n",
    "# 比如constant、invscaling（默认，随迭代次数减小）、optimal（学习率根据损失函数的二阶导数自动调整）\n",
    "# eta0，设置learning_rate的初始值\n",
    "# alpha是正则化力度，通常与 penalty 参数结合使用。当 penalty 设置为 'l2' 时，它实现 L2 正则化，类似于 Ridge；\n",
    "# 当设置为 'l1' 时，它实现 L1 正则化，类似于 Lasso。alpha 参数的值越大，正则化强度越大.\n",
    "# max_iter 最大迭代次数\n",
    "sgd = SGDRegressor(eta0=0.01, penalty='l2',max_iter=1000)\n",
    "\n",
    "# 训练\n",
    "sgd.fit(x_train, y_train)\n",
    "\n",
    "print('梯度下降的回归系数', sgd.coef_)\n",
    "\n",
    "# 预测测试集的房子价格\n",
    "# y_sgd_predict = std_y.inverse_transform(sgd.predict(x_test).reshape(-1, 1))\n",
    "y_predict = sgd.predict(x_test)\n",
    "\n",
    "# print(\"梯度下降测试集里面每个房子的预测价格：\", y_sgd_predict)\n",
    "print(\"梯度下降的均方误差：\", mean_squared_error(y_test, y_predict))\n",
    "# print(\"梯度下降的原始房价量纲均方误差：\", mean_squared_error(std_y.inverse_transform(y_test), y_sgd_predict))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-22T14:28:07.691924200Z",
     "start_time": "2024-05-22T14:28:07.613136100Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 3、 岭回归\n",
    "### L2正则化"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 0.71942576  0.10518585 -0.23146889  0.26801931 -0.00448083 -0.03495127\n",
      "  -0.78489401 -0.76305881]]\n",
      "(5160, 1)\n",
      "岭回归的均方误差： 0.400824186685544\n"
     ]
    }
   ],
   "source": [
    "# 岭回归是对线性回归加入L2正则化，L2正则化是对系数的平方和进行惩罚\n",
    "# alpha就是补偿的系数\n",
    "# 正规方程求解，加补偿就可以让正规方程可逆\n",
    "rd = Ridge(alpha=0.02)\n",
    "\n",
    "rd.fit(x_train, y_train)\n",
    "\n",
    "print(rd.coef_) # 回归系数\n",
    "\n",
    "# 预测测试集的房子价格\n",
    "\n",
    "# y_rd_predict = std_y.inverse_transform(rd.predict(x_test))\n",
    "y_predict = rd.predict(x_test)\n",
    "print(y_predict.shape)\n",
    "# print(\"岭回归里面每个房子的预测价格：\", y_rd_predict)\n",
    "\n",
    "print(\"岭回归的均方误差：\", mean_squared_error(y_test, y_predict))\n",
    "# print(\"岭回归的均方误差：\", mean_squared_error(std_y.inverse_transform(y_test), y_rd_predict))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-22T14:27:51.156948700Z",
     "start_time": "2024-05-22T14:27:51.116811300Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 4、 Lasso回归\n",
    "### L1正则化\n"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 0.71431792  0.10613811 -0.21758465  0.25415162 -0.00311065 -0.03403136\n",
      " -0.77399969 -0.75154125]\n",
      "(5160,)\n",
      "--------------------------------------------------\n",
      "Lasso回归的均方误差： 0.40081302952916903\n"
     ]
    }
   ],
   "source": [
    "# alpha就是补偿的系数\n",
    "\n",
    "ls = Lasso(alpha=0.001)\n",
    "\n",
    "ls.fit(x_train, y_train)\n",
    "\n",
    "print(ls.coef_)\n",
    "\n",
    "# 预测测试集的房子价格\n",
    "print(ls.predict(x_test).shape)\n",
    "print('-'*50)\n",
    "# y_ls_predict = std_y.inverse_transform(ls.predict(x_test).reshape(-1,1))\n",
    "y_predict = ls.predict(x_test)\n",
    "# print(\"Lasso回归里面每个房子的预测价格：\", y_rd_predict)\n",
    "\n",
    "print(\"Lasso回归的均方误差：\", mean_squared_error(y_test, y_predict))\n",
    "# print(\"Lasso回归的均方误差：\", mean_squared_error(std_y.inverse_transform(y_test), y_ls_predict))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-22T14:27:53.687183400Z",
     "start_time": "2024-05-22T14:27:53.533595200Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "# 5、 逻辑回归"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "训练集有很多个样本（早已贴好标签，y=1或0）。\n",
    "寻找一个线性方程，Z = XW，其中W是待求参数。\n",
    "整个逻辑回归要做的就是：y=1的样本尽可能Z>0且越大越好，y=0的样本尽可能Z<0且越小越好。\n",
    "在空间上，这些样本点就落在了两个区域，方程就像是划分这两个区域的一条线\\面\n",
    "\n",
    "P = sigmoid(Z) = 样本被判为1的概率，当Z越大，P越大，该样本被判为1的概率越大\n",
    "\n",
    "似然损失函数，L(W) = -Σ[ yi * logPi + (1-yi) * log(1-Pi) ]\n",
    "当真实值yi=1时，Z越大，pi越大，被判为1的概率越大，损失越小。如果Z<0，则pi<0.5，这时被判为0，同时损失很大，说明分错类了\n",
    "当真实值yi=0时，Z越小，pi越小，被判为1的概率越小，则判为0的概率越大，损失越小\n",
    "\n"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "outputs": [
    {
     "data": {
      "text/plain": "<Figure size 640x480 with 1 Axes>",
      "image/png": "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r7zSWLlypVFcXGwsW7bM2LhxY5CThy5fr/lLL71kOJ1O46WXXjKKi4uN9957z8jMzDR+8pOfBDl56FmyZIlx3333GW+88YYhyVi8ePFpzy8qKjJiYmKMe+65x9i+fbvxxBNPGBEREca7777rt0y9slhMmjTJmDt3btc/ezweIysry1iwYMFJz7/uuuuMq666qtuxyZMnG7fffntAc1qJr9f8q9rb2w2Xy2W8+OKLgYpoKT253u3t7cb5559v/OlPfzLmzJlDsThLvl7rp556ysjLyzNaW1uDFdFyfL3mc+fONS655JJux+655x5j2rRpAc1pNWdTLH72s58Zw4cP73bs+uuvN6644gq/5eh1t0JaW1u1bt06zZw5s+uY3W7XzJkztWrVqpO+Z9WqVd3Ol6QrrrjilOeju55c869qbGxUW1ubkpOTAxXTMnp6vX/zm98oPT1d3/ve94IR0xJ6cq3/8Y9/aOrUqZo7d64yMjI0YsQIPfjgg/J4PMGKHdJ6cs3PP/98rVu3rut2SVFRkZYsWaIrr7wyKJnDSTC+L4O+CdmZVFdXy+PxKCMjo9vxjIwM7dy586TvKS8vP+n55eXlActpJT255l/185//XFlZWSf8gcWJenK9V65cqeeee04bN24MQkLr6Mm1Lioq0kcffaTZs2dryZIl2rNnj+688061tbVp/vz5wYgd0npyzW+88UZVV1dr+vTpMgxD7e3tuuOOO/SLX/wiGJHDyqm+L91ut5qamtSnT59z/oxeN2KB0PPQQw9p0aJFWrx4saKjo82OYzl1dXW66aab9Oyzzyo1NdXsOJbn9XqVnp6uP/7xjxo/fryuv/563XfffXr66afNjmZZy5Yt04MPPqgnn3xS69ev1xtvvKG3335bDzzwgNnR0AO9bsQiNTVVERERqqio6Ha8oqJCffv2Pel7+vbt69P56K4n17zTI488ooceekgffvihRo0aFciYluHr9d67d6/27dunWbNmdR3zer2SpMjISBUWFio/Pz+woUNUT/5sZ2ZmKioqShEREV3Hhg0bpvLycrW2tsrhcAQ0c6jryTX/93//d9100036/ve/L0kaOXKkGhoadNttt+m+++6T3c7/B/aXU31fxsfH+2W0QuqFIxYOh0Pjx4/X0qVLu455vV4tXbpUU6dOPel7pk6d2u18Sfrggw9OeT6668k1l6SHH35YDzzwgN59911NmDAhGFEtwdfrPXToUG3ZskUbN27sel199dW6+OKLtXHjRuXk5AQzfkjpyZ/tadOmac+ePV3lTZJ27dqlzMxMSsVZ6Mk1b2xsPKE8dBY7g+2s/Coo35d+mwbqR4sWLTKcTqfxwgsvGNu3bzduu+02IzEx0SgvLzcMwzBuuukm49577+06/9NPPzUiIyONRx55xNixY4cxf/58Hjf1ka/X/KGHHjIcDofx+uuvG2VlZV2vuro6s/4VQoqv1/ureCrk7Pl6rQ8cOGC4XC7jrrvuMgoLC4233nrLSE9PN/7jP/7DrH+FkOPrNZ8/f77hcrmMV155xSgqKjLef/99Iz8/37juuuvM+lcIGXV1dcaGDRuMDRs2GJKMRx991NiwYYOxf/9+wzAM49577zVuuummrvM7Hzf96U9/auzYscNYuHBheDxuahiG8cQTTxi5ubmGw+EwJk2aZKxevbrrZxdeeKExZ86cbuf/9a9/NQYPHmw4HA5j+PDhxttvvx3kxKHPl2vev39/Q9IJr/nz5wc/eIjy9c/4l1EsfOPrtf7ss8+MyZMnG06n08jLyzN++9vfGu3t7UFOHdp8ueZtbW3Gr3/9ayM/P9+Ijo42cnJyjDvvvNM4evRo8IOHmI8//vikfxd3Xt85c+YYF1544QnvGTNmjOFwOIy8vDzj+eef92smtk0HAAB+0+vmWAAAgNBFsQAAAH5DsQAAAH5DsQAAAH5DsQAAAH5DsQAAAH5DsQAAAH5DsQAAAH5DsQAAAH5DsQAAAH5DsQAAAH5DsQAAAH7z/wEe1awvkWrbjAAAAABJRU5ErkJggg=="
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "x=np.arange(0.01,1,0.01)\n",
    "import matplotlib.pyplot as plt\n",
    "plt.plot(x,-np.log(x))  #以e为底部，\n",
    "plt.show()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-12T16:24:15.002264100Z",
     "start_time": "2024-05-12T16:24:14.853902300Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "outputs": [
    {
     "data": {
      "text/plain": "<Figure size 640x480 with 1 Axes>",
      "image/png": "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"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "x=np.arange(0,1,0.01)\n",
    "import matplotlib.pyplot as plt\n",
    "plt.plot(x,-np.log(1-x))\n",
    "plt.show()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-12T16:24:23.095149Z",
     "start_time": "2024-05-12T16:24:22.958068400Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 逻辑回归做二分类进行癌症预测（根据细胞的属性特征）"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 699 entries, 0 to 698\n",
      "Data columns (total 11 columns):\n",
      " #   Column                       Non-Null Count  Dtype \n",
      "---  ------                       --------------  ----- \n",
      " 0   Sample code number           699 non-null    int64 \n",
      " 1   Clump Thickness              699 non-null    int64 \n",
      " 2   Uniformity of Cell Size      699 non-null    int64 \n",
      " 3   Uniformity of Cell Shape     699 non-null    int64 \n",
      " 4   Marginal Adhesion            699 non-null    int64 \n",
      " 5   Single Epithelial Cell Size  699 non-null    int64 \n",
      " 6   Bare Nuclei                  699 non-null    object\n",
      " 7   Bland Chromatin              699 non-null    int64 \n",
      " 8   Normal Nucleoli              699 non-null    int64 \n",
      " 9   Mitoses                      699 non-null    int64 \n",
      " 10  Class                        699 non-null    int64 \n",
      "dtypes: int64(10), object(1)\n",
      "memory usage: 60.2+ KB\n",
      "None\n",
      "--------------------------------------------------\n",
      "        Sample code number  Clump Thickness  Uniformity of Cell Size  \\\n",
      "count         6.990000e+02       699.000000               699.000000   \n",
      "unique                 NaN              NaN                      NaN   \n",
      "top                    NaN              NaN                      NaN   \n",
      "freq                   NaN              NaN                      NaN   \n",
      "mean          1.071704e+06         4.417740                 3.134478   \n",
      "std           6.170957e+05         2.815741                 3.051459   \n",
      "min           6.163400e+04         1.000000                 1.000000   \n",
      "25%           8.706885e+05         2.000000                 1.000000   \n",
      "50%           1.171710e+06         4.000000                 1.000000   \n",
      "75%           1.238298e+06         6.000000                 5.000000   \n",
      "max           1.345435e+07        10.000000                10.000000   \n",
      "\n",
      "        Uniformity of Cell Shape  Marginal Adhesion  \\\n",
      "count                 699.000000         699.000000   \n",
      "unique                       NaN                NaN   \n",
      "top                          NaN                NaN   \n",
      "freq                         NaN                NaN   \n",
      "mean                    3.207439           2.806867   \n",
      "std                     2.971913           2.855379   \n",
      "min                     1.000000           1.000000   \n",
      "25%                     1.000000           1.000000   \n",
      "50%                     1.000000           1.000000   \n",
      "75%                     5.000000           4.000000   \n",
      "max                    10.000000          10.000000   \n",
      "\n",
      "        Single Epithelial Cell Size Bare Nuclei  Bland Chromatin  \\\n",
      "count                    699.000000         699       699.000000   \n",
      "unique                          NaN          11              NaN   \n",
      "top                             NaN           1              NaN   \n",
      "freq                            NaN         402              NaN   \n",
      "mean                       3.216023         NaN         3.437768   \n",
      "std                        2.214300         NaN         2.438364   \n",
      "min                        1.000000         NaN         1.000000   \n",
      "25%                        2.000000         NaN         2.000000   \n",
      "50%                        2.000000         NaN         3.000000   \n",
      "75%                        4.000000         NaN         5.000000   \n",
      "max                       10.000000         NaN        10.000000   \n",
      "\n",
      "        Normal Nucleoli     Mitoses       Class  \n",
      "count        699.000000  699.000000  699.000000  \n",
      "unique              NaN         NaN         NaN  \n",
      "top                 NaN         NaN         NaN  \n",
      "freq                NaN         NaN         NaN  \n",
      "mean           2.866953    1.589413    2.689557  \n",
      "std            3.053634    1.715078    0.951273  \n",
      "min            1.000000    1.000000    2.000000  \n",
      "25%            1.000000    1.000000    2.000000  \n",
      "50%            1.000000    1.000000    2.000000  \n",
      "75%            4.000000    1.000000    4.000000  \n",
      "max           10.000000   10.000000    4.000000  \n"
     ]
    }
   ],
   "source": [
    "# 构造列标签名字\n",
    "column = ['Sample code number', 'Clump Thickness', 'Uniformity of Cell Size', 'Uniformity of Cell Shape',\n",
    "          'Marginal Adhesion', 'Single Epithelial Cell Size', 'Bare Nuclei', 'Bland Chromatin', 'Normal Nucleoli',\n",
    "          'Mitoses', 'Class']\n",
    "\n",
    "# 读取数据\n",
    "# data = pd.read_csv(\n",
    "#     \"https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data\",\n",
    "#     names=column)\n",
    "data = pd.read_csv(\"data/breast-cancer-wisconsin.csv\", names=column)\n",
    "\n",
    "# 当你读取数据时，看上去是数值的列，读进来是字符串，说明里边存在非数值特征\n",
    "print(data.info())\n",
    "print(\"-\"*50)\n",
    "\n",
    "print(data.describe(include='all'))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-22T14:36:18.435353100Z",
     "start_time": "2024-05-22T14:36:18.359898900Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "outputs": [
    {
     "data": {
      "text/plain": "(699, 11)"
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.shape"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-22T14:36:27.115850800Z",
     "start_time": "2024-05-22T14:36:27.055555500Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['1' '10' '2' '4' '3' '9' '7' '?' '5' '8' '6']\n"
     ]
    }
   ],
   "source": [
    "print(data['Bare Nuclei'].unique())"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-22T14:36:28.741580200Z",
     "start_time": "2024-05-22T14:36:28.716649100Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(683, 11)\n"
     ]
    }
   ],
   "source": [
    "# 缺失值进行处理\n",
    "data = data.replace(to_replace='?', value=np.nan)\n",
    "# 直接删除，哪一行有空值，就删除对应的样本\n",
    "data = data.dropna()\n",
    "\n",
    "print(data.shape)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-22T14:36:30.698050500Z",
     "start_time": "2024-05-22T14:36:30.671765Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Index: 683 entries, 0 to 698\n",
      "Data columns (total 11 columns):\n",
      " #   Column                       Non-Null Count  Dtype \n",
      "---  ------                       --------------  ----- \n",
      " 0   Sample code number           683 non-null    int64 \n",
      " 1   Clump Thickness              683 non-null    int64 \n",
      " 2   Uniformity of Cell Size      683 non-null    int64 \n",
      " 3   Uniformity of Cell Shape     683 non-null    int64 \n",
      " 4   Marginal Adhesion            683 non-null    int64 \n",
      " 5   Single Epithelial Cell Size  683 non-null    int64 \n",
      " 6   Bare Nuclei                  683 non-null    object\n",
      " 7   Bland Chromatin              683 non-null    int64 \n",
      " 8   Normal Nucleoli              683 non-null    int64 \n",
      " 9   Mitoses                      683 non-null    int64 \n",
      " 10  Class                        683 non-null    int64 \n",
      "dtypes: int64(10), object(1)\n",
      "memory usage: 64.0+ KB\n"
     ]
    }
   ],
   "source": [
    "data.info()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-22T14:36:32.162963200Z",
     "start_time": "2024-05-22T14:36:32.108073100Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "outputs": [
    {
     "data": {
      "text/plain": "array([2, 4], dtype=int64)"
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 分类的类别是2和4,对应 \"良性\", \"恶性\"\n",
    "data[column[10]].unique()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-22T14:36:34.726089300Z",
     "start_time": "2024-05-22T14:36:34.701993300Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "outputs": [],
   "source": [
    "# 进行数据的分割,第零列是编号\n",
    "x_train, x_test, y_train, y_test = train_test_split(data[column[1:10]],\n",
    "                                                    data[column[10]],\n",
    "                                                    test_size=0.25, random_state=1)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-22T14:36:38.923800400Z",
     "start_time": "2024-05-22T14:36:38.906847700Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "<class 'pandas.core.frame.DataFrame'>\n",
      "<class 'pandas.core.series.Series'>\n",
      "<class 'pandas.core.series.Series'>\n"
     ]
    }
   ],
   "source": [
    "print(type(x_train))\n",
    "print(type(x_test))\n",
    "print(type(y_train))\n",
    "print(type(y_test))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-22T14:36:52.592312500Z",
     "start_time": "2024-05-22T14:36:52.525347200Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "outputs": [],
   "source": [
    "# 进行标准化处理\n",
    "std = StandardScaler()\n",
    "\n",
    "x_train = std.fit_transform(x_train)\n",
    "x_test = std.transform(x_test)\n"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-22T14:36:57.637359300Z",
     "start_time": "2024-05-22T14:36:57.599626400Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'numpy.ndarray'>\n",
      "[-1.21629973 -0.70863282 -0.75174943  0.04301674 -0.55657068 -0.71054972\n",
      " -0.99312055 -0.62911518 -0.36280962]\n"
     ]
    }
   ],
   "source": [
    "print(type(x_train))\n",
    "print(x_train[0])"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-22T14:37:12.819807200Z",
     "start_time": "2024-05-22T14:37:12.775713400Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(512, 9)\n",
      "(171, 9)\n",
      "(512,)\n",
      "(171,)\n"
     ]
    }
   ],
   "source": [
    "print(x_train.shape)\n",
    "print(x_test.shape)\n",
    "print(y_train.shape)\n",
    "print(y_test.shape)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-22T14:37:22.862709900Z",
     "start_time": "2024-05-22T14:37:22.794884500Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1.1133701  0.25198952 0.79297925 0.61016803 0.07140358 1.10923362\n",
      "  0.77824325 0.64387342 0.67841755]]\n",
      "--------------------------------------------------\n",
      "[2 2 2 4 2 4 2 2 4 4 2 2 4 2 2 4 2 2 2 2 2 2 2 4 4 2 2 2 4 4 2 2 4 4 2 4 2\n",
      " 2 4 4 4 2 2 4 2 2 2 2 4 2 2 2 4 2 2 2 4 2 2 2 2 4 2 2 2 4 2 4 4 2 2 4 2 2\n",
      " 4 2 2 2 2 2 2 2 4 2 4 4 2 2 2 4 2 2 4 2 2 4 4 2 2 4 2 2 4 4 2 2 2 2 4 2 4\n",
      " 4 2 4 2 4 2 2 2 2 4 2 4 2 2 2 2 2 4 2 2 2 2 2 2 2 4 2 4 4 2 2 4 2 2 2 2 4\n",
      " 2 2 2 2 2 4 2 4 2 4 2 2 4 2 4 2 4 4 2 4 2 2 2]\n",
      "准确率： 0.9824561403508771\n",
      "--------------------------------------------------\n",
      "[[9.49055860e-01 5.09441403e-02]\n",
      " [9.94951356e-01 5.04864403e-03]\n",
      " [9.83692948e-01 1.63070522e-02]\n",
      " [2.69465805e-02 9.73053420e-01]\n",
      " [9.97326877e-01 2.67312287e-03]\n",
      " [7.07379938e-04 9.99292620e-01]\n",
      " [9.91945714e-01 8.05428616e-03]\n",
      " [9.92204547e-01 7.79545284e-03]\n",
      " [7.10879193e-04 9.99289121e-01]\n",
      " [6.55499402e-04 9.99344501e-01]\n",
      " [9.87584036e-01 1.24159640e-02]\n",
      " [9.96201488e-01 3.79851191e-03]\n",
      " [1.32714502e-03 9.98672855e-01]\n",
      " [7.07201257e-01 2.92798743e-01]\n",
      " [9.88095286e-01 1.19047143e-02]\n",
      " [2.61504382e-03 9.97384956e-01]\n",
      " [9.88000738e-01 1.19992620e-02]\n",
      " [9.19674815e-01 8.03251851e-02]\n",
      " [9.89355019e-01 1.06449805e-02]\n",
      " [9.48509379e-01 5.14906206e-02]\n",
      " [9.80482413e-01 1.95175871e-02]\n",
      " [9.97326877e-01 2.67312287e-03]\n",
      " [9.88951335e-01 1.10486654e-02]\n",
      " [4.70715473e-01 5.29284527e-01]\n",
      " [9.70987481e-02 9.02901252e-01]\n",
      " [9.91846436e-01 8.15356378e-03]\n",
      " [9.94133379e-01 5.86662129e-03]\n",
      " [9.95025152e-01 4.97484776e-03]\n",
      " [1.01121007e-02 9.89887899e-01]\n",
      " [3.91921212e-01 6.08078788e-01]\n",
      " [9.64786506e-01 3.52134943e-02]\n",
      " [9.96038692e-01 3.96130797e-03]\n",
      " [2.05163046e-02 9.79483695e-01]\n",
      " [4.26248502e-01 5.73751498e-01]\n",
      " [9.88095286e-01 1.19047143e-02]\n",
      " [3.95210198e-01 6.04789802e-01]\n",
      " [9.91945714e-01 8.05428616e-03]\n",
      " [9.94133379e-01 5.86662129e-03]\n",
      " [3.15429880e-02 9.68457012e-01]\n",
      " [1.96590837e-03 9.98034092e-01]\n",
      " [3.99052058e-03 9.96009479e-01]\n",
      " [9.83804017e-01 1.61959831e-02]\n",
      " [9.34936624e-01 6.50633761e-02]\n",
      " [9.58792316e-04 9.99041208e-01]\n",
      " [9.91031683e-01 8.96831703e-03]\n",
      " [9.97326877e-01 2.67312287e-03]\n",
      " [9.88951335e-01 1.10486654e-02]\n",
      " [9.94133379e-01 5.86662129e-03]\n",
      " [1.88574807e-04 9.99811425e-01]\n",
      " [9.87712861e-01 1.22871392e-02]\n",
      " [9.93924099e-01 6.07590121e-03]\n",
      " [9.82436716e-01 1.75632844e-02]\n",
      " [2.49091860e-02 9.75090814e-01]\n",
      " [9.79659588e-01 2.03404122e-02]\n",
      " [9.72939203e-01 2.70607969e-02]\n",
      " [9.87173771e-01 1.28262295e-02]\n",
      " [1.71580118e-03 9.98284199e-01]\n",
      " [9.96325667e-01 3.67433263e-03]\n",
      " [9.92526979e-01 7.47302135e-03]\n",
      " [9.83692948e-01 1.63070522e-02]\n",
      " [5.17324857e-01 4.82675143e-01]\n",
      " [4.91253829e-06 9.99995087e-01]\n",
      " [9.36105826e-01 6.38941744e-02]\n",
      " [9.92526979e-01 7.47302135e-03]\n",
      " [9.82436716e-01 1.75632844e-02]\n",
      " [4.72921053e-02 9.52707895e-01]\n",
      " [9.94133379e-01 5.86662129e-03]\n",
      " [2.10386535e-03 9.97896135e-01]\n",
      " [1.81840593e-06 9.99998182e-01]\n",
      " [9.83149049e-01 1.68509512e-02]\n",
      " [9.90759862e-01 9.24013842e-03]\n",
      " [2.49317957e-03 9.97506820e-01]\n",
      " [9.75992692e-01 2.40073082e-02]\n",
      " [9.87173771e-01 1.28262295e-02]\n",
      " [1.25263641e-01 8.74736359e-01]\n",
      " [9.82436716e-01 1.75632844e-02]\n",
      " [9.87173771e-01 1.28262295e-02]\n",
      " [9.85306277e-01 1.46937234e-02]\n",
      " [9.94951356e-01 5.04864403e-03]\n",
      " [9.85192166e-01 1.48078343e-02]\n",
      " [9.94557630e-01 5.44237050e-03]\n",
      " [9.94951356e-01 5.04864403e-03]\n",
      " [6.56576240e-03 9.93434238e-01]\n",
      " [9.95114075e-01 4.88592456e-03]\n",
      " [1.18078042e-02 9.88192196e-01]\n",
      " [2.95334457e-04 9.99704666e-01]\n",
      " [9.76154937e-01 2.38450632e-02]\n",
      " [9.76232478e-01 2.37675224e-02]\n",
      " [9.40131964e-01 5.98680361e-02]\n",
      " [2.85338941e-03 9.97146611e-01]\n",
      " [9.97326877e-01 2.67312287e-03]\n",
      " [9.93576820e-01 6.42317967e-03]\n",
      " [3.65932266e-03 9.96340677e-01]\n",
      " [9.96043588e-01 3.95641198e-03]\n",
      " [9.96201488e-01 3.79851191e-03]\n",
      " [5.96851439e-02 9.40314856e-01]\n",
      " [4.28274595e-02 9.57172540e-01]\n",
      " [9.70284729e-01 2.97152709e-02]\n",
      " [9.94557630e-01 5.44237050e-03]\n",
      " [3.59608565e-02 9.64039143e-01]\n",
      " [9.94557630e-01 5.44237050e-03]\n",
      " [9.65083100e-01 3.49168999e-02]\n",
      " [1.98042371e-02 9.80195763e-01]\n",
      " [1.08401289e-03 9.98915987e-01]\n",
      " [9.69933619e-01 3.00663808e-02]\n",
      " [9.91945714e-01 8.05428616e-03]\n",
      " [9.81537291e-01 1.84627094e-02]\n",
      " [9.84824314e-01 1.51756855e-02]\n",
      " [5.35673209e-04 9.99464327e-01]\n",
      " [9.95196303e-01 4.80369670e-03]\n",
      " [1.46284996e-03 9.98537150e-01]\n",
      " [1.26375773e-01 8.73624227e-01]\n",
      " [9.75992692e-01 2.40073082e-02]\n",
      " [2.53916000e-03 9.97460840e-01]\n",
      " [9.91678359e-01 8.32164147e-03]\n",
      " [1.08609653e-02 9.89139035e-01]\n",
      " [9.83692948e-01 1.63070522e-02]\n",
      " [9.88095286e-01 1.19047143e-02]\n",
      " [9.11223933e-01 8.87760670e-02]\n",
      " [9.94133379e-01 5.86662129e-03]\n",
      " [7.53576778e-04 9.99246423e-01]\n",
      " [9.26858175e-01 7.31418247e-02]\n",
      " [1.15113461e-03 9.98848865e-01]\n",
      " [9.76337017e-01 2.36629830e-02]\n",
      " [9.94322311e-01 5.67768858e-03]\n",
      " [9.97413232e-01 2.58676817e-03]\n",
      " [9.92526979e-01 7.47302135e-03]\n",
      " [9.96325667e-01 3.67433263e-03]\n",
      " [1.81532771e-05 9.99981847e-01]\n",
      " [9.70440544e-01 2.95594559e-02]\n",
      " [9.97326877e-01 2.67312287e-03]\n",
      " [9.94557630e-01 5.44237050e-03]\n",
      " [9.94951356e-01 5.04864403e-03]\n",
      " [9.96444251e-01 3.55574937e-03]\n",
      " [9.89484311e-01 1.05156891e-02]\n",
      " [9.80838020e-01 1.91619800e-02]\n",
      " [1.44372052e-02 9.85562795e-01]\n",
      " [9.68809317e-01 3.11906829e-02]\n",
      " [2.43626205e-03 9.97563738e-01]\n",
      " [1.76643683e-01 8.23356317e-01]\n",
      " [6.91626697e-01 3.08373303e-01]\n",
      " [9.94430141e-01 5.56985931e-03]\n",
      " [1.32311461e-01 8.67688539e-01]\n",
      " [9.96038692e-01 3.96130797e-03]\n",
      " [9.91319633e-01 8.68036737e-03]\n",
      " [9.94951356e-01 5.04864403e-03]\n",
      " [9.96325667e-01 3.67433263e-03]\n",
      " [5.94239402e-05 9.99940576e-01]\n",
      " [9.97326877e-01 2.67312287e-03]\n",
      " [9.94765954e-01 5.23404572e-03]\n",
      " [9.88095286e-01 1.19047143e-02]\n",
      " [9.81686962e-01 1.83130384e-02]\n",
      " [9.54084966e-01 4.59150336e-02]\n",
      " [9.24001291e-02 9.07599871e-01]\n",
      " [9.94951356e-01 5.04864403e-03]\n",
      " [2.33107609e-05 9.99976689e-01]\n",
      " [9.82452565e-01 1.75474351e-02]\n",
      " [1.42241722e-02 9.85775828e-01]\n",
      " [9.96325667e-01 3.67433263e-03]\n",
      " [9.91319633e-01 8.68036737e-03]\n",
      " [1.66135879e-04 9.99833864e-01]\n",
      " [9.94133379e-01 5.86662129e-03]\n",
      " [2.73670446e-03 9.97263296e-01]\n",
      " [9.78354492e-01 2.16455081e-02]\n",
      " [6.36845025e-03 9.93631550e-01]\n",
      " [1.05152559e-01 8.94847441e-01]\n",
      " [9.93721999e-01 6.27800131e-03]\n",
      " [2.66850817e-01 7.33149183e-01]\n",
      " [9.83692948e-01 1.63070522e-02]\n",
      " [9.78335673e-01 2.16643274e-02]\n",
      " [9.92204547e-01 7.79545284e-03]]\n",
      "--------------------------------------------------\n",
      "精确率召回率：\n",
      "               precision    recall  f1-score   support\n",
      "\n",
      "          良性       0.97      1.00      0.99       111\n",
      "          恶性       1.00      0.95      0.97        60\n",
      "\n",
      "    accuracy                           0.98       171\n",
      "   macro avg       0.99      0.97      0.98       171\n",
      "weighted avg       0.98      0.98      0.98       171\n",
      "\n",
      "AUC指标： 0.975\n"
     ]
    }
   ],
   "source": [
    "# C正则化力度的倒数\n",
    "# solver = 'liblinear'  solver是学习率优化算法，就是学习率会随着epoch的变化而变化\n",
    "# epoch就代表第几次迭代\n",
    "# max_iter 最大迭代次数\n",
    "lg = LogisticRegression(C=0.5, solver='lbfgs')\n",
    "\n",
    "# 训练\n",
    "lg.fit(x_train, y_train)\n",
    "print(lg.coef_) # 逻辑回归的权重参数，了解，没那么重要\n",
    "print('-'*50)\n",
    "\n",
    "y_predict = lg.predict(x_test)\n",
    "print(y_predict)\n",
    "print(\"准确率：\", lg.score(x_test, y_test))\n",
    "print('-'*50)\n",
    "\n",
    "# 得出对应分类的概率\n",
    "print(lg.predict_proba(x_test))\n",
    "print('-'*50)\n",
    "\n",
    "# 为什么还要看下召回率，labels和target_names对应\n",
    "# macro avg 平均值  weighted avg 加权平均值\n",
    "print(\"精确率召回率：\\n\", classification_report(y_test, y_predict, labels=[2, 4], target_names=[\"良性\", \"恶性\"]))\n",
    "# AUC计算要求是二分类，不需要是0和1\n",
    "print(\"AUC指标：\", roc_auc_score(y_test, y_predict))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-13T04:51:04.463197800Z",
     "start_time": "2024-05-13T04:51:04.426828100Z"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
